﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using YJKArch.Utils;

namespace YJKArch.AreaStatistical.SearchLoop
{
	public class Pole
	{
		public ElementId ComponentId
		{
			get
			{
				return this.m_ComponentId;
			}
		}

		public bool IsPositiveDirection
		{
			get
			{
				return this.m_PositiveDirection;
			}
		}

		public bool IsArcPole
		{
			get
			{
				return !Geometry.IsEqual(this.m_Bulge, 0.0);
			}
		}

		public XYZ StartPoint
		{
			get
			{
				return this.m_ptStart;
			}
			set
			{
				this.m_ptStart = Pole.XYZ2D(value);
			}
		}

		public XYZ EndPoint
		{
			get
			{
				return this.m_ptEnd;
			}
			set
			{
				this.m_ptEnd = Pole.XYZ2D(value);
			}
		}

		public XYZ PositiveStartPoint
		{
			get
			{
				return this.m_ptPositiveStart;
			}
		}

		public XYZ PositiveEndPoint
		{
			get
			{
				return this.m_ptPositiveEnd;
			}
		}

		public XYZ NegativeStartPoint
		{
			get
			{
				return this.m_ptNegativeStart;
			}
		}

		public XYZ NegativeEndPoint
		{
			get
			{
				return this.m_ptNegativeEnd;
			}
		}

		public double Bulge
		{
			get
			{
				return this.m_Bulge;
			}
		}

		public double PositiveHalfWidth
		{
			get
			{
				double result;
				if (this.IsArcPole)
				{
					XYZ xyz = null;
					Geometry.GetCenterWithBulge(this.m_ptStart, this.m_ptEnd, this.m_Bulge, ref xyz);
					result = this.m_ptPositiveStart.DistanceTo(xyz) - this.Radius;
				}
				else
				{
					result = Geometry.CalculateFootPoint(this.m_ptStart, this.m_ptEnd, this.m_ptPositiveStart).DistanceTo(this.m_ptPositiveStart);
				}
				return result;
			}
		}

		public double NegativeHalfWidth
		{
			get
			{
				double result;
				if (this.IsArcPole)
				{
					XYZ xyz = null;
					Geometry.GetCenterWithBulge(this.m_ptStart, this.m_ptEnd, this.m_Bulge, ref xyz);
					result = this.Radius - this.m_ptNegativeStart.DistanceTo(xyz);
				}
				else
				{
					result = Geometry.CalculateFootPoint(this.m_ptStart, this.m_ptEnd, this.m_ptNegativeStart).DistanceTo(this.m_ptNegativeStart);
				}
				return result;
			}
		}

		public XYZ Center
		{
			get
			{
				if (Geometry.IsEqual(this.m_Bulge, 0.0))
				{
					return null;
				}
				XYZ result = null;
				Geometry.GetCenterWithBulge(this.m_ptStart, this.m_ptEnd, this.m_Bulge, ref result);
				return result;
			}
		}

		public double Radius
		{
			get
			{
				if (Geometry.IsEqual(this.m_Bulge, 0.0))
				{
					return double.MaxValue;
				}
				double result = 0.0;
				Geometry.GetRadiusWithBulge(this.m_ptStart, this.m_ptEnd, this.m_Bulge, ref result);
				return result;
			}
		}

		public Element Element
		{
			get
			{
				return this.m_Element;
			}
			private set
			{
				this.m_Element = value;
			}
		}

		public RevitLinkInstance UseRevitLinkInstance
		{
			get
			{
				return this.m_useRevitLinkInstance;
			}
			private set
			{
				this.m_useRevitLinkInstance = value;
			}
		}

		public double Length()
		{
			if (this.IsArcPole)
			{
				XYZ xyz = null;
				Geometry.GetCenterWithBulge(this.StartPoint, this.EndPoint, this.Bulge, ref xyz);
				double num = xyz.DistanceTo(this.StartPoint);
				double angle = Geometry.getAngle(xyz, this.StartPoint);
				double angle2 = Geometry.getAngle(xyz, this.EndPoint);
				double num2 = Geometry.BetweenTheAngles(angle, angle2, true);
				if (Geometry.LessThan(this.Bulge, 0.0))
				{
					num2 = Geometry.BetweenTheAngles(angle2, angle, true);
				}
				return num2 * num;
			}
			return this.StartPoint.DistanceTo(this.EndPoint);
		}

		public Curve ToCurve(Autodesk.Revit.DB.Document doc, bool isBound)
		{
			if (this.IsArcPole)
			{
				XYZ xyz = XYZ.BasisZ;
				if (Geometry.LessThan(this.Bulge, 0.0))
				{
					xyz = -xyz;
				}
				if (isBound)
				{
					XYZ radianPnt = Geometry.CalculatMidPoint(this.StartPoint, this.EndPoint, this.Center, xyz);
					return doc.CreatYJKArc(this.StartPoint, this.EndPoint, radianPnt);
				}
				XYZ center = this.Center;
				double radius = this.Radius;
				XYZ startPnt = center - XYZ.BasisX * radius;
				XYZ endPnt = center + Geometry.RotateTo(XYZ.BasisX, 3.12413936106985, xyz) * radius;
				XYZ radianPnt2 = center + XYZ.BasisX * radius;
				return doc.CreatYJKArc(startPnt, endPnt, radianPnt2);
			}
			else
			{
				if (isBound)
				{
					return YJKLineEx.YJKGetBound(this.StartPoint, this.EndPoint);
				}
				return YJKLineEx.YJKGetUnBound(this.StartPoint, this.EndPoint - this.StartPoint);
			}
		}

		public void GetEndsLine(ref List<Pole> endsLineList)
		{
			if (Geometry.IsEqual(this.PositiveHalfWidth + this.NegativeHalfWidth, 0.0))
			{
				return;
			}
			Pole item = Pole.NewPole(this.ComponentId, this.m_ptNegativeStart, this.StartPoint, 0.0, 0.0);
			endsLineList.Add(item);
			Pole item2 = Pole.NewPole(this.ComponentId, this.m_ptPositiveStart, this.StartPoint, 0.0, 0.0);
			endsLineList.Add(item2);
			Pole item3 = Pole.NewPole(this.ComponentId, this.m_ptNegativeEnd, this.EndPoint, 0.0, 0.0);
			endsLineList.Add(item3);
			Pole item4 = Pole.NewPole(this.ComponentId, this.m_ptPositiveEnd, this.EndPoint, 0.0, 0.0);
			endsLineList.Add(item4);
		}

		public bool SameAs(Pole rhs)
		{
			return (this.m_ptStart.IsAlmostEqualTo(rhs.m_ptStart) && this.m_ptEnd.IsAlmostEqualTo(rhs.m_ptEnd) && Geometry.IsEqual(this.m_Bulge, rhs.m_Bulge)) || (this.m_ptStart.IsAlmostEqualTo(rhs.m_ptEnd) && this.m_ptEnd.IsAlmostEqualTo(rhs.m_ptStart) && Geometry.IsEqual(-this.m_Bulge, rhs.m_Bulge));
		}

		private Pole._tagPositionType TestPointPositionType(XYZ ptCurNodePos)
		{
			double val = this.m_ptStart.DistanceTo(ptCurNodePos);
			double val2 = this.m_ptEnd.DistanceTo(ptCurNodePos);
			if (Geometry.LessThan(val, val2))
			{
				return Pole._tagPositionType._StartNode;
			}
			if (Geometry.GreaterThan(val, val2))
			{
				return Pole._tagPositionType._EndNode;
			}
			return Pole._tagPositionType._StartNode;
		}

		public bool GetAngle(XYZ ptCurNodePos, ref double curAngle)
		{
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				if (!this.IsArcPole)
				{
					curAngle = Geometry.getAngle(this.m_ptStart, this.m_ptEnd);
				}
				else if (Geometry.LessThan(this.m_Bulge, 0.0))
				{
					XYZ ptCenter = new XYZ(0.0, 0.0, 0.0);
					Geometry.GetCenterWithBulge(this.m_ptStart, this.m_ptEnd, this.m_Bulge, ref ptCenter);
					curAngle = Geometry.getAngle(ptCenter, this.m_ptStart);
					curAngle = Geometry.formatAngle(curAngle - Math.PI*.5);
				}
				else
				{
					XYZ ptCenter2 = new XYZ(0.0, 0.0, 0.0);
					Geometry.GetCenterWithBulge(this.m_ptStart, this.m_ptEnd, this.m_Bulge, ref ptCenter2);
					curAngle = Geometry.getAngle(ptCenter2, this.m_ptStart);
					curAngle = Geometry.formatAngle(curAngle + Math.PI*.5);
				}
				return true;
			}
			if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				if (!this.IsArcPole)
				{
					curAngle = Geometry.getAngle(this.m_ptEnd, this.m_ptStart);
				}
				else if (Geometry.LessThan(this.m_Bulge, 0.0))
				{
					XYZ ptCenter3 = new XYZ(0.0, 0.0, 0.0);
					Geometry.GetCenterWithBulge(this.m_ptStart, this.m_ptEnd, this.m_Bulge, ref ptCenter3);
					curAngle = Geometry.getAngle(ptCenter3, this.m_ptEnd);
					curAngle = Geometry.formatAngle(curAngle + Math.PI*.5);
				}
				else
				{
					XYZ ptCenter4 = new XYZ(0.0, 0.0, 0.0);
					Geometry.GetCenterWithBulge(this.m_ptStart, this.m_ptEnd, this.m_Bulge, ref ptCenter4);
					curAngle = Geometry.getAngle(ptCenter4, this.m_ptEnd);
					curAngle = Geometry.formatAngle(curAngle - Math.PI*.5);
				}
				return true;
			}
			return false;
		}

		public bool GetWinding(XYZ ptCurNodePos, ref int winding)
		{
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				winding = 1;
				if (!this.IsArcPole)
				{
					winding = 0;
				}
				if (Geometry.LessThan(this.m_Bulge, 0.0))
				{
					winding = -1;
				}
				return true;
			}
			if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				winding = -1;
				if (!this.IsArcPole)
				{
					winding = 0;
				}
				if (Geometry.LessThan(this.m_Bulge, 0.0))
				{
					winding = 1;
				}
				return true;
			}
			return false;
		}

		public void SetIsPositiveDirection(XYZ ptCurNodePos)
		{
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				this.m_PositiveDirection = true;
				return;
			}
			if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				this.m_PositiveDirection = false;
			}
		}

		public XYZ CurStartPoint(XYZ ptCurNodePos)
		{
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				return this.m_ptStart;
			}
			if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				return this.m_ptEnd;
			}
			return null;
		}

		public XYZ CurEndPoint(XYZ ptCurNodePos)
		{
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				return this.m_ptEnd;
			}
			if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				return this.m_ptStart;
			}
			return null;
		}

		public double CurBulge(XYZ ptCurNodePos)
		{
			double result = 0.0;
			if (!this.IsArcPole)
			{
				return result;
			}
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				result = this.m_Bulge;
			}
			else if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				result = -this.m_Bulge;
			}
			return result;
		}

		public XYZ CurPositiveStartPoint(XYZ ptCurNodePos)
		{
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				return this.m_ptPositiveStart;
			}
			if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				return this.m_ptNegativeEnd;
			}
			return null;
		}

		public XYZ CurPositiveEndPoint(XYZ ptCurNodePos)
		{
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				return this.m_ptPositiveEnd;
			}
			if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				return this.m_ptNegativeStart;
			}
			return null;
		}

		public bool SetCurPositiveStartPoint(XYZ ptCurNodePos, XYZ ptNewPos)
		{
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				if (this.IsArcPole)
				{
					XYZ center = this.Center;
					double arcAngle = this.GetArcAngle(center, this.m_ptPositiveStart, this.m_ptPositiveEnd);
					if (Geometry.GreaterThan(Math.Abs(this.GetArcAngle(center, ptNewPos, this.m_ptPositiveEnd) - arcAngle), Math.PI))
					{
						return false;
					}
				}
				else
				{
					XYZ xyz = (this.m_ptPositiveEnd - this.m_ptPositiveStart).Normalize();
					XYZ xyz2 = (this.m_ptPositiveEnd - ptNewPos).Normalize();
					if (!xyz.IsAlmostEqualTo(xyz2))
					{
						return false;
					}
				}
				this.m_ptPositiveStart = ptNewPos;
				return true;
			}
			if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				if (this.IsArcPole)
				{
					XYZ center2 = this.Center;
					double arcAngle2 = this.GetArcAngle(center2, this.m_ptNegativeStart, this.m_ptNegativeEnd);
					if (Geometry.GreaterThan(Math.Abs(this.GetArcAngle(center2, this.m_ptNegativeStart, ptNewPos) - arcAngle2), Math.PI))
					{
						return false;
					}
				}
				else
				{
					XYZ xyz3 = (this.m_ptNegativeEnd - this.m_ptNegativeStart).Normalize();
					XYZ xyz4 = (ptNewPos - this.m_ptNegativeStart).Normalize();
					if (!xyz3.IsAlmostEqualTo(xyz4))
					{
						return false;
					}
				}
				this.m_ptNegativeEnd = ptNewPos;
				return true;
			}
			return false;
		}

		public XYZ CurNegativeStartPoint(XYZ ptCurNodePos)
		{
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				return this.m_ptNegativeStart;
			}
			if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				return this.m_ptPositiveEnd;
			}
			return null;
		}

		public XYZ CurNegativeEndPoint(XYZ ptCurNodePos)
		{
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				return this.m_ptNegativeEnd;
			}
			if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				return this.m_ptPositiveStart;
			}
			return null;
		}

		public bool SetCurNegativeStartPoint(XYZ ptCurNodePos, XYZ ptNewPos)
		{
			Pole._tagPositionType tagPositionType = this.TestPointPositionType(ptCurNodePos);
			if (tagPositionType == Pole._tagPositionType._StartNode)
			{
				if (this.IsArcPole)
				{
					XYZ center = this.Center;
					double arcAngle = this.GetArcAngle(center, this.m_ptNegativeStart, this.m_ptNegativeEnd);
					if (Geometry.GreaterThan(Math.Abs(this.GetArcAngle(center, ptNewPos, this.m_ptNegativeEnd) - arcAngle), Math.PI))
					{
						return false;
					}
				}
				else
				{
					XYZ xyz = (this.m_ptNegativeEnd - this.m_ptNegativeStart).Normalize();
					XYZ xyz2 = (this.m_ptNegativeEnd - ptNewPos).Normalize();
					if (!xyz.IsAlmostEqualTo(xyz2))
					{
						return false;
					}
				}
				this.m_ptNegativeStart = ptNewPos;
				return true;
			}
			if (tagPositionType == Pole._tagPositionType._EndNode)
			{
				if (this.IsArcPole)
				{
					XYZ center2 = this.Center;
					double arcAngle2 = this.GetArcAngle(center2, this.m_ptPositiveStart, this.m_ptPositiveEnd);
					if (Geometry.GreaterThan(Math.Abs(this.GetArcAngle(center2, this.m_ptPositiveStart, ptNewPos) - arcAngle2), Math.PI))
					{
						return false;
					}
				}
				else
				{
					XYZ xyz3 = (this.m_ptPositiveEnd - this.m_ptPositiveStart).Normalize();
					XYZ xyz4 = (ptNewPos - this.m_ptPositiveStart).Normalize();
					if (!xyz3.IsAlmostEqualTo(xyz4))
					{
						return false;
					}
				}
				this.m_ptPositiveEnd = ptNewPos;
				return true;
			}
			return false;
		}

		private double GetArcAngle(XYZ ptCenter, XYZ ptStart, XYZ ptEnd)
		{
			double angle = Geometry.getAngle(ptCenter, ptStart);
			double angle2 = Geometry.getAngle(ptCenter, ptEnd);
			return Geometry.BetweenTheAngles(angle, angle2, true);
		}

		private static XYZ XYZ2D(XYZ pt)
		{
			return new XYZ(pt.X, pt.Y, 0.0);
		}

		public Pole(Pole rhs)
		{
			this.m_ComponentId = rhs.m_ComponentId;
			this.m_ptStart = rhs.m_ptStart;
			this.m_ptEnd = rhs.m_ptEnd;
			this.m_Bulge = rhs.m_Bulge;
			this.m_ptPositiveStart = rhs.m_ptPositiveStart;
			this.m_ptPositiveEnd = rhs.m_ptPositiveEnd;
			this.m_ptNegativeStart = rhs.m_ptNegativeStart;
			this.m_ptNegativeEnd = rhs.m_ptNegativeEnd;
			this.m_PositiveDirection = rhs.m_PositiveDirection;
		}

		public Pole(ElementId componentId, XYZ ptStart, XYZ ptEnd, double bulge, XYZ ptPositiveStart, XYZ ptPositiveEnd, XYZ ptNegativeStart, XYZ ptNegativeEnd, bool positiveDirection)
		{
			ptStart = Pole.XYZ2D(ptStart);
			ptEnd = Pole.XYZ2D(ptEnd);
			this.m_ComponentId = componentId;
			this.m_ptStart = ptStart;
			this.m_ptEnd = ptEnd;
			this.m_Bulge = bulge;
			this.m_ptPositiveStart = ptPositiveStart;
			this.m_ptPositiveEnd = ptPositiveEnd;
			this.m_ptNegativeStart = ptNegativeStart;
			this.m_ptNegativeEnd = ptNegativeEnd;
			this.m_PositiveDirection = positiveDirection;
		}

		public static Pole NewPole(ElementId id, XYZ ptStart, XYZ ptEnd, double posiHalfWidth, double negaHalfWidth)
		{
			ptStart = Pole.XYZ2D(ptStart);
			ptEnd = Pole.XYZ2D(ptEnd);
			XYZ xyz = Geometry.RotateTo((ptEnd - ptStart).Normalize(), -Math.PI*.5, XYZ.BasisZ);
			XYZ xyz2 = xyz.Negate();
			xyz *= posiHalfWidth;
			xyz2 *= negaHalfWidth;
			XYZ ptPositiveStart = ptStart + xyz;
			XYZ ptPositiveEnd = ptEnd + xyz;
			XYZ ptNegativeStart = ptStart + xyz2;
			XYZ ptNegativeEnd = ptEnd + xyz2;
			return new Pole(id, ptStart, ptEnd, 0.0, ptPositiveStart, ptPositiveEnd, ptNegativeStart, ptNegativeEnd, true);
		}

		public static Pole NewPole(ElementId id, XYZ ptStart, XYZ ptEnd, XYZ ptCenter, XYZ normal, double posiHalfWidth, double negaHalfWidth)
		{
			ptStart = Pole.XYZ2D(ptStart);
			ptEnd = Pole.XYZ2D(ptEnd);
			ptCenter = Pole.XYZ2D(ptCenter);
			if (!normal.IsAlmostEqualTo(XYZ.BasisZ))
			{
				XYZ xyz = ptStart;
				ptStart = ptEnd;
				ptEnd = xyz;
			}
			double bulge = Geometry.GetBulge(ptStart, ptEnd, ptCenter, true);
			double num = ptCenter.DistanceTo(ptStart);
			XYZ xyz2 = (ptStart - ptCenter).Normalize() * (num + posiHalfWidth);
			XYZ xyz3 = (ptEnd - ptCenter).Normalize() * (num + posiHalfWidth);
			XYZ xyz4 = (ptStart - ptCenter).Normalize() * (num - negaHalfWidth);
			XYZ xyz5 = (ptEnd - ptCenter).Normalize() * (num - negaHalfWidth);
			XYZ ptPositiveStart = ptCenter + xyz2;
			XYZ ptPositiveEnd = ptCenter + xyz3;
			XYZ ptNegativeStart = ptCenter + xyz4;
			XYZ ptNegativeEnd = ptCenter + xyz5;
			return new Pole(id, ptStart, ptEnd, bulge, ptPositiveStart, ptPositiveEnd, ptNegativeStart, ptNegativeEnd, true);
		}

		public static Pole TransformWallToPole(Wall wall)
		{
			double width = wall.Width;
			Pole result = null;
			Curve curve = (wall.Location as LocationCurve).Curve;
			XYZ ptStart = Pole.XYZ2D(curve.GetEndPoint(0));
			XYZ ptEnd = Pole.XYZ2D(curve.GetEndPoint(1));
			Line line = curve as Line;
			if (null != line)
			{
				result = Pole.NewPole(wall.Id, ptStart, ptEnd, width / 2.0, width / 2.0);
			}
			Arc arc = curve as Arc;
			if (null != arc)
			{
				result = Pole.NewPole(wall.Id, ptStart, ptEnd, Pole.XYZ2D(arc.Center), arc.Normal, width / 2.0, width / 2.0);
			}
			return result;
		}

		public static Pole TransformWallToPole(Curve curve, ElementId id, double posiWidth, double negaWidth)
		{
			Pole result = null;
			XYZ ptStart = Pole.XYZ2D(curve.GetEndPoint(0));
			XYZ ptEnd = Pole.XYZ2D(curve.GetEndPoint(1));
			Line line = curve as Line;
			if (null != line)
			{
				result = Pole.NewPole(id, ptStart, ptEnd, posiWidth, negaWidth);
			}
			Arc arc = curve as Arc;
			if (null != arc)
			{
				result = Pole.NewPole(id, ptStart, ptEnd, Pole.XYZ2D(arc.Center), arc.Normal, posiWidth, negaWidth);
			}
			return result;
		}

		public static Pole TransformWallToPole(Wall wall, RevitLinkInstance inputRevitLinkInstance)
		{
			double width = wall.Width;
			Pole result = null;
			Curve curve = (wall.Location as LocationCurve).Curve;
			if (inputRevitLinkInstance != null)
			{
				curve = curve.CreateTransformed(inputRevitLinkInstance.GetTotalTransform());
			}
			XYZ ptStart = Pole.XYZ2D(curve.GetEndPoint(0));
			XYZ ptEnd = Pole.XYZ2D(curve.GetEndPoint(1));
			Line line = curve as Line;
			if (null != line)
			{
				result = Pole.NewPole(wall, inputRevitLinkInstance, ptStart, ptEnd, width / 2.0, width / 2.0);
			}
			Arc arc = curve as Arc;
			if (null != arc)
			{
				result = Pole.NewPole(wall, inputRevitLinkInstance, ptStart, ptEnd, Pole.XYZ2D(arc.Center), arc.Normal, width / 2.0, width / 2.0);
			}
			return result;
		}

		public static Pole TransformWallToPole(Curve curve, Element inputElement, RevitLinkInstance inputRevitLinkInstance, double posiWidth, double negaWidth)
		{
			Pole result = null;
			XYZ ptStart = Pole.XYZ2D(curve.GetEndPoint(0));
			XYZ ptEnd = Pole.XYZ2D(curve.GetEndPoint(1));
			Line line = curve as Line;
			if (null != line)
			{
				result = Pole.NewPole(inputElement, inputRevitLinkInstance, ptStart, ptEnd, posiWidth, negaWidth);
			}
			Arc arc = curve as Arc;
			if (null != arc)
			{
				result = Pole.NewPole(inputElement, inputRevitLinkInstance, ptStart, ptEnd, Pole.XYZ2D(arc.Center), arc.Normal, posiWidth, negaWidth);
			}
			return result;
		}

		public Pole(Element inputElement, RevitLinkInstance inputRevitLinkInstance, XYZ ptStart, XYZ ptEnd, double bulge, XYZ ptPositiveStart, XYZ ptPositiveEnd, XYZ ptNegativeStart, XYZ ptNegativeEnd, bool positiveDirection)
		{
			this.Element = inputElement;
			this.UseRevitLinkInstance = inputRevitLinkInstance;
			if (inputElement != null)
			{
				this.m_ComponentId = inputElement.Id;
			}
			ptStart = Pole.XYZ2D(ptStart);
			ptEnd = Pole.XYZ2D(ptEnd);
			this.m_ptStart = ptStart;
			this.m_ptEnd = ptEnd;
			this.m_Bulge = bulge;
			this.m_ptPositiveStart = ptPositiveStart;
			this.m_ptPositiveEnd = ptPositiveEnd;
			this.m_ptNegativeStart = ptNegativeStart;
			this.m_ptNegativeEnd = ptNegativeEnd;
			this.m_PositiveDirection = positiveDirection;
		}

		public static Pole NewPole(Element inputElement, RevitLinkInstance inputRevitLinkInstance, XYZ ptStart, XYZ ptEnd, double posiHalfWidth, double negaHalfWidth)
		{
			ptStart = Pole.XYZ2D(ptStart);
			ptEnd = Pole.XYZ2D(ptEnd);
			XYZ xyz = Geometry.RotateTo((ptEnd - ptStart).Normalize(), -Math.PI*.5, XYZ.BasisZ);
			XYZ xyz2 = xyz.Negate();
			xyz *= posiHalfWidth;
			xyz2 *= negaHalfWidth;
			XYZ ptPositiveStart = ptStart + xyz;
			XYZ ptPositiveEnd = ptEnd + xyz;
			XYZ ptNegativeStart = ptStart + xyz2;
			XYZ ptNegativeEnd = ptEnd + xyz2;
			return new Pole(inputElement, inputRevitLinkInstance, ptStart, ptEnd, 0.0, ptPositiveStart, ptPositiveEnd, ptNegativeStart, ptNegativeEnd, true);
		}

		public static Pole NewPole(Element inputElement, RevitLinkInstance inputRevitLinkInstance, XYZ ptStart, XYZ ptEnd, XYZ ptCenter, XYZ normal, double posiHalfWidth, double negaHalfWidth)
		{
			ptStart = Pole.XYZ2D(ptStart);
			ptEnd = Pole.XYZ2D(ptEnd);
			ptCenter = Pole.XYZ2D(ptCenter);
			if (!normal.IsAlmostEqualTo(XYZ.BasisZ))
			{
				XYZ xyz = ptStart;
				ptStart = ptEnd;
				ptEnd = xyz;
			}
			double bulge = Geometry.GetBulge(ptStart, ptEnd, ptCenter, true);
			double num = ptCenter.DistanceTo(ptStart);
			XYZ xyz2 = (ptStart - ptCenter).Normalize() * (num + posiHalfWidth);
			XYZ xyz3 = (ptEnd - ptCenter).Normalize() * (num + posiHalfWidth);
			XYZ xyz4 = (ptStart - ptCenter).Normalize() * (num - negaHalfWidth);
			XYZ xyz5 = (ptEnd - ptCenter).Normalize() * (num - negaHalfWidth);
			XYZ ptPositiveStart = ptCenter + xyz2;
			XYZ ptPositiveEnd = ptCenter + xyz3;
			XYZ ptNegativeStart = ptCenter + xyz4;
			XYZ ptNegativeEnd = ptCenter + xyz5;
			return new Pole(inputElement, inputRevitLinkInstance, ptStart, ptEnd, bulge, ptPositiveStart, ptPositiveEnd, ptNegativeStart, ptNegativeEnd, true);
		}

		private ElementId m_ComponentId;

		private XYZ m_ptStart;

		private XYZ m_ptEnd;

		private double m_Bulge;

		private XYZ m_ptPositiveStart;

		private XYZ m_ptPositiveEnd;

		private XYZ m_ptNegativeStart;

		private XYZ m_ptNegativeEnd;

		private bool m_PositiveDirection = true;

		private Element m_Element;

		private RevitLinkInstance m_useRevitLinkInstance;

		private enum _tagPositionType
		{
			_StartNode,
			_EndNode,
			_OtherPoint
		}
	}
}
